package com.hejing.bpeldesign.bpel;

import com.hejing.bpeldesign.bpelprase.BpelNodeFactory;
import com.hejing.bpeldesign.model.*;
import org.w3c.dom.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import java.util.*;

public class BpelParser {
    public static BpelProcessModel parse(InputStream inputStream) throws Exception {
        BpelProcessModel model = new BpelProcessModel();

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(inputStream);

        Element process = document.getDocumentElement();
        NodeList allElements = process.getElementsByTagName("*");

        List<Element> nodeElements = new ArrayList<>();
        Map<Element, BpelNode> elementToNode = new HashMap<>();

        for (int i = 0; i < allElements.getLength(); i++) {
            Element el = (Element) allElements.item(i);
            if (!el.hasAttribute("bounds")) continue;
            BpelNode node = BpelNodeFactory.parse(el);
            model.nodes.add(node);
            nodeElements.add(el);
            elementToNode.put(el, node);
        }



        // Step 2: 解析连线（保持你已有的结构）
        for (int i = 0; i < nodeElements.size(); i++) {
            Element current = nodeElements.get(i);
            BpelNode currentNode = elementToNode.get(current);
            String tagName = current.getTagName();

            if ("note".equalsIgnoreCase(tagName)) continue;

            // 特殊节点处理逻辑（如 while、switchstart、switchend）
            // 建议你这里复用你已有逻辑即可，无需修改

            // 默认连线（上一个节点 → 当前节点）
            for (int j = i - 1; j >= 0; j--) {
                Element prev = nodeElements.get(j);
                if (!prev.hasAttribute("bounds")) continue;
                BpelNode fromNode = elementToNode.get(prev);

                NodeList sourceList = current.getElementsByTagName("source");
                if (sourceList.getLength() > 0) {
                    Element sourceEL = (Element) sourceList.item(0);
                    String terminal = sourceEL.getAttribute("terminal");
                    model.edges.add(new BpelEdge(fromNode, currentNode, terminal));
                }
                break;
            }
        }

        return model;
    }
}
